module anem_prepbufr_mod

  use datetime
  use container
  use flogger
  use params_mod
  use cli_mod
  use data_translators_utils_mod
  use anem_mod

  implicit none

  private

  public anem_prepbufr_write

  integer, parameter :: max_num_var = 10
  integer, parameter :: max_num_lev = 1
  integer, parameter :: max_num_event = 2

contains

  subroutine anem_prepbufr_write(file_path, towers, records)

    character(*), intent(inout) :: file_path
    type(hash_table_type), intent(in) :: towers
    type(linked_list_type), intent(in) :: records

    type(linked_list_iterator_type) it
    integer idate, iret
    real(8) hdr(max_num_var)
    real(8) obs(max_num_var,max_num_lev,max_num_event)
    real(8) oe(max_num_var,max_num_lev,max_num_event)
    real(8) qc(max_num_var,max_num_lev,max_num_event)

    if (file_path == '') file_path ='anem.prepbufr'

    hdr = missing_value_in_prepbufr
    obs = missing_value_in_prepbufr
    oe  = missing_value_in_prepbufr
    qc  = missing_value_in_prepbufr

    call log_notice('Writing ' // trim(file_path) // ' ...')
    open(10, file=file_path, action='write', form='unformatted')
    open(11, file=trim(exe_dir) // '/../notes/prepobs_prep.bufrtable')
    call datelen(10) ! This call causes idate to be in format YYYYMMDDHH.
    call openbf(10, 'OUT', 11)
    it = linked_list_iterator(records)
    do while (.not. it%ended())
      select type (record => it%value)
      type is (anem_record_type)
        idate = record%time%year * 1000000 + record%time%month * 10000 + record%time%day * 100 + record%time%hour
        call openmb(10, 'PROFLR', idate)
        hdr(1) = transfer(record%tower%name, hdr(1))
        hdr(2) = merge(record%tower%lon, record%tower%lon - 360, record%tower%lon < 180)
        hdr(3) = record%tower%lat
        hdr(4) = 0.0
        hdr(5) = 223
        hdr(6) = record%tower%z
        call ufbint(10, hdr, max_num_var, 1, iret, 'SID XOB YOB DHR TYP ELV SAID T29')
        obs(4,1,1) = merge(add(record%h, record%tower%z), real(missing_value_in_prepbufr), .not. is_missing(record%h))
        obs(5,1,1) = merge(record%ua_avg, real(missing_value_in_prepbufr), .not. is_missing(record%ua_avg))
        obs(6,1,1) = merge(record%va_avg, real(missing_value_in_prepbufr), .not. is_missing(record%va_avg))
        obs(8,1,1) = 3
        call ufbint(10, obs, max_num_var, 1, iret, 'POB QOB TOB ZOB UOB VOB PWO CAT PRSS')
        oe(5,1,1) = 2.0
        call ufbint(10, oe , max_num_var, 1, iret, 'POE QOE TOE NUL WOE NUL PWE')
        qc(1,1,1) = 2
        qc(5,1,1) = 2
        call ufbint(10, qc , max_num_var, 1, iret, 'PQM QQM TQM ZQM WQM NUL PWQ')
        call writsb(10)
        call closmg(10)
      end select
      call it%next()
    end do
    call closbf(10)

  end subroutine anem_prepbufr_write

end module anem_prepbufr_mod
